#import "MRMapOverlay.h"
#import "UIView+Extension.h"

/*===================================================================
 说明:
	地图标签
 ==================================================================*/
@implementation MRAnnotation

+ (id)annotationWithCoordinate:(CLLocationCoordinate2D)coordinate
{
	return [MRAnnotation annotationWithCoordinate:coordinate style:MRAnnotationStyleFree];
}

+ (id)annotationWithCoordinate:(CLLocationCoordinate2D)coordinate style:(MRAnnotationStyle)style
{
	MRAnnotation *a = [[MRAnnotation alloc] init];
	a.coordinate = coordinate;
	a.style = style;
	return a;
}

- (void)setCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated
{
	[_timer invalidate];
	
	if (animated)
	{
		_count  = 50;
		_start  = self.coordinate;
		_target = coordinate;
		_timer  = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(timerProc) userInfo:nil repeats:YES];
	}
	else
	{
		self.coordinate = coordinate;
	}
}

- (void)timerProc
{
	if (-- _count)
	{
		CGFloat f = (50.f - _count) / 50.f;
		
		CLLocationDegrees latitude = _start.latitude + (_target.latitude - _start.latitude) * f;
		CLLocationDegrees longitude = _start.longitude + (_target.longitude - _start.longitude) * f;
		
		self.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
	}
	else
	{
		[_timer invalidate];
		self.coordinate = _target;
	}
}

@end

#pragma mark - 标注视图
/*===================================================================
 说明:
	标签视图
 ==================================================================*/
@implementation MRAnnotationView
@dynamic annotation;

+ (instancetype)reuseWithMapView:(MKMapView *)mapView reuseIdentifier:(NSString *)reuseIdentifier
{
	MRAnnotationView *annotationView = (MRAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIdentifier];
	if (annotationView == nil)
	{
		annotationView = [[MRAnnotationView alloc] initWithAnnotation:nil reuseIdentifier:reuseIdentifier];
	}
	
	[annotationView stopAnimating];
	return annotationView;
}

- (instancetype)initWithAnnotation:(MRAnnotation *)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
	if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier])
	{
		self.backgroundColor = [UIColor clearColor];
		
		CGFloat size = LOCPIXEL(DPISCALE(17.5));
		self.bounds = CGRectMake(0, 0, size, size);
		
		_aniLayer = [CAShapeLayer new];
		_aniLayer.opacity = 0;
		
		_bkLayer = [CAShapeLayer new];
		_bkLayer.shadowOffset  = CGSizeZero;
		_bkLayer.shadowOpacity = .2;
		_bkLayer.shadowRadius  = 1.5;
		_bkLayer.shadowColor   = rgb(0, 0, 0).CGColor;
		
		_cirLAyer = [CAShapeLayer new];
		
		[self.layer addSublayer:_aniLayer];
		[self.layer addSublayer:_bkLayer];
		[self.layer addSublayer:_cirLAyer];
		
		_title = [[UILabel alloc] initWithFrame:self.bounds];
		_title.font = [UIFont boldSystemFontOfSize:DPISCALE(8)];
		_title.adjustsFontSizeToFitWidth = YES;
		_title.textColor = [UIColor whiteColor];
		_title.textAlignment = NSTextAlignmentCenter;
		_title.backgroundColor = [UIColor clearColor];
		_title.numberOfLines = 0;
		
		[self addSubview:_title];
	}
	
	return self;
}

- (void)dealloc
{
	[self stopAnimating];
}

- (void)setAnnotation:(MRAnnotation *)annotation
{
	[super setAnnotation:annotation];
	[self setNeedsDisplay];
	
	if (annotation.style == MRAnnotationStyleUser) [self startAnimating];
}

- (void)drawRect:(CGRect)rect
{
	_title.text  = self.annotation.text;
	_title.frame = CGRectInset(self.bounds, LOCPIXEL(DPISCALE(3)), LOCPIXEL(DPISCALE(3)));
	
	rect = CGRectOffset(self.bounds, -CGRectGetMidX(self.bounds), -CGRectGetMidY(self.bounds));
	UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:self.bounds.size.width / 2];
	
	_aniLayer.path = _bkLayer.path = _cirLAyer.path = path.CGPath;
	_aniLayer.position = _bkLayer.position = _cirLAyer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
	
	_bkLayer.fillColor  = [UIColor whiteColor].CGColor;
	_bkLayer.shadowPath = path.CGPath;
	
	_color = self.annotation.color;
	if (!_color) _color = [MRSkinManager skin].skinColor;
	
	_cirLAyer.fillColor = _color.CGColor;
	_cirLAyer.transform = CATransform3DMakeScale(.75, .75, 1);
}

#pragma mark - 标注动画
/*===================================================================
 说明:
	定位动画
 ==================================================================*/
- (void)startAnimating
{
	if (!_timer)
	{
		_timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(timerProc) userInfo:nil repeats:YES];
		[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
	}
}

- (void)stopAnimating
{
	[_timer invalidate];
	_timer = nil;
	
	[_aniLayer removeAllAnimations];
	[_cirLAyer removeAllAnimations];
}

- (void)timerProc
{
	_aniLayer.fillColor = [_color colorWithAlphaComponent:.6].CGColor;
	
	CGFloat scale = [UIScreen mainScreen].bounds.size.width / self.bounds.size.width / 3;
	
	CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
	scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
	scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(scale, scale, 1)];
	
	CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
	opacityAnimation.fromValue = @.8;
	opacityAnimation.toValue = @0;
	
	CAAnimationGroup *animation = [CAAnimationGroup animation];
	animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
	animation.animations = @[scaleAnimation, opacityAnimation];
	animation.duration = 2;
	
	[_aniLayer removeAllAnimations];
	[_aniLayer addAnimation:animation forKey:nil];
	
	CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
	animation1.duration = 2;
	animation1.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(.75, .75, 1)],
						  [NSValue valueWithCATransform3D:CATransform3DMakeScale(.5, .5, 1)],
						  [NSValue valueWithCATransform3D:CATransform3DMakeScale(.8, .8, 1)],
						  [NSValue valueWithCATransform3D:CATransform3DMakeScale(.75, .75, 1)]];
	
	[_cirLAyer removeAllAnimations];
	[_cirLAyer addAnimation:animation1 forKey:nil];
}

@end

#pragma mark - 轨迹
@implementation MRPolyline
+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords colors:(ARGBCOLOR *)colors count:(NSUInteger)count
{
	MRPolyline *polyline = [MRPolyline polylineWithCoordinates:coords count:count];
	polyline->_colors = colors;
	
	return polyline;
}

@end

#pragma mark - 运动轨迹
/*===================================================================
 说明:
	地图轨迹视图
 ==================================================================*/
@implementation MRPolylineView
@dynamic polyline;

/*===================================================================
 说明:
	初始化轨迹
 ==================================================================*/
- (instancetype)initWithPolyline:(MRPolyline *)polyline
{
	if (self = [super initWithPolyline:polyline])
	{
		self.lineCap = kCGLineCapButt;
		self.lineJoin = kCGLineJoinRound;
	}
	
	return self;
}

/*====================================================================
 说明:
	绘制轨迹
 ===================================================================*/
typedef void(^OBUIBezierPathEnumerationHandler)(const CGPathElement *element);
void CGPathEnumerationCallback(void *info, const CGPathElement *element)
{
	OBUIBezierPathEnumerationHandler handler = (__bridge OBUIBezierPathEnumerationHandler)(info);
	if (handler) handler(element);
}

- (void)strokePath:(CGPathRef)path inContext:(CGContextRef)context
{
	CGFloat lineWidth = CGContextConvertSizeToUserSpace(context, CGSizeMake(self.lineWidth, self.lineWidth)).width;
	
	//轨迹背景
	CGContextSetLineWidth(context, lineWidth * 1.2);
	CGContextAddPath(context, path);
	CGContextStrokePath(context);
	
	if (!self.polyline.colors)	//单色填充
	{
		if (self.fillColor)
		{
			CGPathRef thickPath = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, kCGLineCapButt, kCGLineJoinRound, 0);
			CGContextAddPath(context, thickPath);
			
			CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
			CGContextFillPath(context);
			CGPathRelease(thickPath);
		}
		return;
	}
	
	//获取当前路径点及对应颜色索引
	__block int clrIndex = 1;
	NSMutableArray *points = [NSMutableArray array];
	NSMutableArray *colors = [NSMutableArray array];
	
	OBUIBezierPathEnumerationHandler handler = ^(const CGPathElement *element) {
		
		switch ((int)element->type)
		{
			case kCGPathElementMoveToPoint:
				[points addObject:[NSValue valueWithCGPoint:element->points[0]]];
				[colors addObject:@0];
				break;
				
			case kCGPathElementAddLineToPoint:
				[points addObject:[NSValue valueWithCGPoint:element->points[0]]];
				
				for (; clrIndex<self.polyline.pointCount; clrIndex++)
				{
					CGPoint point = [self pointForMapPoint:self.polyline.points[clrIndex]];
					
					if (CGPointEqualToPoint(element->points[0], point))
					{
						[colors addObject:@(clrIndex)];
						break;
					}
				}
				break;
		}
	};
	
	CGPathApply(path, (__bridge void *)(handler), CGPathEnumerationCallback);
	
	//特效轨迹
	if (!points.count) return;
	
	CGRect rect = CGContextGetClipBoundingBox(context);
	CGPoint last = [points[0] CGPointValue];

	for (NSInteger i=1; i<points.count; i++)
	{
		CGPoint point = [points[i] CGPointValue];
		CGRect rc = CGRectMake(MIN(point.x, last.x), MIN(point.y, last.y), ABS(point.x - last.x), ABS(point.y - last.y));
		
		if (CGRectIntersectsRect(rect, CGRectInset(rc, -lineWidth/2, -lineWidth/2)))
		{
			CGMutablePathRef subpath = CGPathCreateMutable();
			CGPathMoveToPoint(subpath, NULL, last.x, last.y);
			CGPathAddLineToPoint(subpath, NULL, point.x , point.y);
			
			if (i < points.count-1)		//绘制到第三点，解决绘制断裂现象
			{
				CGPoint pt = [points[i+1] CGPointValue];
				CGPathAddLineToPoint(subpath, NULL, pt.x , pt.y);
			}
			
			CGContextSaveGState(context);
			
			CGPathRef thickPath = CGPathCreateCopyByStrokingPath(subpath, NULL, lineWidth, kCGLineCapButt, kCGLineJoinRound, 0);
			CGContextAddPath(context, thickPath);
			CGContextClip(context);
			
			ARGBCOLOR clr = self.polyline.colors[[colors[i-1] intValue]];
			UIColor *clr1 = rgba(clr.r, clr.g, clr.b, clr.a / 255.f);
			
			clr = self.polyline.colors[[colors[i] intValue]];
			UIColor *clr2 = rgba(clr.r, clr.g, clr.b, clr.a / 255.f);
			
			[UIView drawLinearGradient:context colors:@[clr1, clr2] startPoint:last endPoint:point];
			
			CGPathRelease(thickPath);
			CGPathRelease(subpath);
			CGContextRestoreGState(context);
		}
		
		last = point;
	}
}

@end

#pragma mark - 背景层
@implementation MRMapBackground

- (instancetype)initWithColor:(UIColor *)color
{
	if (self = [super init])
	{
		_boundingMapRect = MKMapRectWorld;
		_fillColor = color;
	}
	
	return self;
}

@end

/*===================================================================
 说明:
	轨迹背景层
 ==================================================================*/
@implementation MRMapBackgroundView

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
{
	CGRect rect = [self rectForMapRect:mapRect];
	
	CGContextSetFillColorWithColor(context, self.fillColor.CGColor);
	CGContextFillRect(context, rect);
}

- (void)setFillColor:(UIColor *)fillColor
{
	_fillColor = fillColor;
	[self setNeedsDisplay];
}

@end
